//
//  NSObject+QMRequest.m
//  Qunmi
//
//  Created by 吴仁辉 on 2018/4/7.
//  Copyright © 2018年 Aaron. All rights reserved.
//

#import "NSObject+QMRequest.h"
#import <objc/runtime.h>
//static NSMutableArray *propertysArr=nil;
@interface NSObject()
@property(nonatomic,strong)NSMutableArray *propertysArr;
@end
@implementation NSObject (QMRequest)
-(NSArray*)ingoreArray{
    return nil;
}
-(NSDictionary*)otherClassesInClassArray{
    return nil;
}
- (NSDictionary *)replacePropertyWithKey {
    return nil;
}
-(BOOL)isNotNeedParentProperty{
   return objc_getAssociatedObject(self, @"isNotNeedParentProperty");
}
-(void)setIsNotNeedParentProperty:(BOOL)isNotNeedParentProperty{
       objc_setAssociatedObject(self, @"isNotNeedParentProperty", @(isNotNeedParentProperty), OBJC_ASSOCIATION_ASSIGN);
}
/**关联对象*/
-(NSMutableArray*)propertysArr{
    return objc_getAssociatedObject(self, @"ModelPropertysArr");
}

-(void)setPropertysArr:(NSMutableArray *)propertysArr{
    objc_setAssociatedObject(self, @"ModelPropertysArr", propertysArr, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/**父类的递归调用，一直递归去拿到父类的属性列表，*/
-(void)getPropertyListOfClass:(Class)zlass{
    //     NSLog(@"zlass --%@",zlass);
    if (![NSStringFromClass(zlass) isEqualToString:@"NSObject"]) {
//        NSLog(@"Subclass --%@",zlass);
        unsigned int count=0;
        objc_property_t *propertys =   class_copyPropertyList(zlass, &count);
        if (![self isNotNeedParentProperty]) {//.先加载父类的属性列表
            [self getPropertyListOfClass:[zlass superclass]];
        }
        for (int i=0; i<count; i++) {//，加载完父类的列表之后，再加载自身的属性列表
            objc_property_t property =propertys[i];
            NSString*  propertyName   =      [NSString stringWithCString: property_getName(property) encoding:NSUTF8StringEncoding];
            
            [self.propertysArr addObject:propertyName];
        }
        if (!self.isNotNeedParentProperty) {//递归调用
            [self getPropertyListOfClass:[zlass superclass]];
        }
    }else{
        NSLog(@"这是最顶级的父类了NSObject ");
    }
}
/**拿到属性列表，只有 [self otherClassesInClassArray]有值，就会一直递归去调用*/
-(NSDictionary*)getDictFrommemberList{
    if (self.propertysArr==nil) {
        self.propertysArr=[[NSMutableArray alloc]init];
    }
    [self.propertysArr removeAllObjects];
    //递归调用父类，遍历父类的属性列表
    [self getPropertyListOfClass:[self class]];
    NSMutableDictionary*Propertydict=[[NSMutableDictionary alloc]init];
    
    for (int i=0; i<self.propertysArr.count; i++) {
        NSString*propertyName=self.propertysArr[i];
        
        //  忽略数组
        if ([self ingoreArray]&&[self ingoreArray].count>0) {//忽略数组
            if ([[self ingoreArray] containsObject:propertyName]) {
                continue;
            }
        }
        
        id value =[self valueForKeyPath:propertyName];
        if ([self otherClassesInClassArray]) {//含有其他的类
            NSDictionary*dict=[self otherClassesInClassArray];
            for (NSString*key in dict.allKeys) {
                if ([propertyName isEqualToString:key]) {//
                    if (!value) {
                        break ;
                    }
                    id obj=[self getObjectWithpropertyName:propertyName];
                    if ([obj isKindOfClass:[NSArray class]]) {//数组
                        NSMutableArray*arrayM=[NSMutableArray array];
                        for (id classObj in obj) {
                            [arrayM addObject: [classObj getDictFrommemberList]];
                        }
                        obj=arrayM;
                        value=arrayM;
                        
                    }else if([obj isKindOfClass:[NSDictionary class]]){//字典
                        NSMutableDictionary*dictM=[NSMutableDictionary dictionary];
                        
                        //                        [dict set]
                        for (NSString*subkey in ((NSDictionary*)obj).allKeys) {
                            [dictM setObject:[((NSDictionary*)obj)[subkey] getDictFrommemberList] forKey:subkey];
                        }
                        obj=dict;
                        value=dictM;
                        
                    }
                    else{//普通的类
                      
                      
                        value=[obj getDictFrommemberList];
                    
                        
                    }
                    break;//  匹配上了 for (NSString*key in dict.allKeys) {循环终止，去匹配下一个propertyName
                }
                else{//属性不是class的普通的属性
                    value =    [self valueForKeyPath:propertyName];//普通的属性
                }
                
            }
        }else{
            NSLog(@"propertyName--%@",propertyName);
            value =    [self valueForKeyPath:propertyName];
        }
        
        
        if(!value){
            continue;
        }
        else  if (( [value isKindOfClass:[NSNumber class]]&&[value intValue]==0)){
            continue;
        }
        //      else  if( [value isKindOfClass:[NSArray class]]&&((NSArray*)value).count==0){
        //            continue;
        //        }
        //      else if ([value isKindOfClass:[NSDictionary class]]&&((NSDictionary*)value).count==0){
        //          continue;
        //      }
        else{
            NSDictionary*replacedict =  [self replacePropertyWithKey];
            if (replacedict.count>0) {
                for (NSString*key in replacedict.allKeys) {
                    if ([propertyName isEqualToString:key]) {
                        propertyName=replacedict[key];
                        break;
                    }
                }
            }
            NSString*isNS =[NSStringFromClass([value class]) substringToIndex:4];
            if ([value isKindOfClass:[NSObject class]]&&![isNS containsString:@"NS"]) {
                NSLog(@"Warning：%@是个类，没有申明，不会加入属性",propertyName);
            }
            else{
                [Propertydict setValue:value forKey:propertyName];
            }
           
        }
    }
    return Propertydict;
    
}
/**model类型属性名称，去调用model的get方法，拿到对应的model值*/
-(id)getObjectWithpropertyName:(NSString*)name{
    SEL selector =NSSelectorFromString(name);
    IMP imp=[self methodForSelector:selector];
    id (*func)(id,SEL)=(void*)imp;
    id obj =func(self,selector);
    return obj;
}
@end

